﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PengSW.ThrMatrix
{
    [Serializable]
    public class ThrMatrix
    {
        public ThrMatrix()
        {
            Data = new double[3, 3];
        }

        public ThrMatrix(double[,] aData)
        {
            Data = new double[3, 3];
            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) Data[i, j] = aData[i, j];
        }

        public double M00 { get { return Data[0, 0]; } set { Data[0, 0] = value; } }
        public double M01 { get { return Data[0, 1]; } set { Data[0, 1] = value; } }
        public double M02 { get { return Data[0, 2]; } set { Data[0, 2] = value; } }
        public double M10 { get { return Data[1, 0]; } set { Data[1, 0] = value; } }
        public double M11 { get { return Data[1, 1]; } set { Data[1, 1] = value; } }
        public double M12 { get { return Data[1, 2]; } set { Data[1, 2] = value; } }
        public double M20 { get { return Data[2, 0]; } set { Data[2, 0] = value; } }
        public double M21 { get { return Data[2, 1]; } set { Data[2, 1] = value; } }
        public double M22 { get { return Data[2, 2]; } set { Data[2, 2] = value; } }

        public double[,] Data { get; private set; }

        public ThrMatrix Star
        {
            get
            {
                ThrMatrix aStar = new ThrMatrix();
                aStar.Data[0, 0] = Data[1, 1] * Data[2, 2] - Data[2, 1] * Data[1, 2];
                aStar.Data[0, 1] = -(Data[0, 1] * Data[2, 2] - Data[0, 2] * Data[2, 1]);
                aStar.Data[0, 2] = Data[0, 1] * Data[1, 2] - Data[0, 2] * Data[1, 1];
                aStar.Data[1, 0] = -(Data[1, 0] * Data[2, 2] - Data[1, 2] * Data[2, 0]);
                aStar.Data[1, 1] = Data[0, 0] * Data[2, 2] - Data[0, 2] * Data[2, 0];
                aStar.Data[1, 2] = -(Data[0, 0] * Data[1, 2] - Data[0, 2] * Data[1, 0]);
                aStar.Data[2, 0] = Data[1, 0] * Data[2, 1] - Data[1, 1] * Data[2, 0];
                aStar.Data[2, 1] = -(Data[0, 0] * Data[2, 1] - Data[0, 1] * Data[2, 0]);
                aStar.Data[2, 2] = Data[0, 0] * Data[1, 1] - Data[0, 1] * Data[1, 0];
                return aStar;
            }
        }

        public ThrMatrix Inverse
        {
            get
            {
                ThrMatrix aInverse = Star;
                double aDet = Det;
                for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) aInverse.Data[i, j] /= aDet;
                return aInverse;
            }
        }

        public double Det
        {
            get
            {
                return Data[0, 0] * Data[1, 1] * Data[2, 2] +
                    Data[0, 1] * Data[1, 2] * Data[2, 0] +
                    Data[0, 2] * Data[1, 0] * Data[2, 1] -
                    Data[0, 0] * Data[1, 2] * Data[2, 1] -
                    Data[0, 1] * Data[1, 0] * Data[2, 2] -
                    Data[0, 2] * Data[1, 1] * Data[2, 0];
            }
        }

        public ThrMatrix MultiWith(ThrMatrix aThrMatrix)
        {
            ThrMatrix aResult = new ThrMatrix();
            for (int i = 0; i < 3; i++)
                for (int j = 0; j < 3; j++)
                    for (int k = 0; k < 3; k++)
                    {
                        aResult.Data[i, j] += Data[i, k] * aThrMatrix.Data[k, j];
                    }
            return aResult;
        }
    }
}
